package chat

import (
	"context"
	"coze_for_sdk/config"
	"coze_for_sdk/controller"
	"coze_for_sdk/controller/auth"
	"coze_for_sdk/logger"
	"coze_for_sdk/model"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"strconv"
	"time"

	"github.com/coze-dev/coze-go"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator"
)

func Create(c *gin.Context) {
	//入参接收
	createParams := struct {
		ConversationId string `json:"conversation_id" validate:"required"`
		Message        string `json:"message" validate:"required"`
	}{}
	if err := c.ShouldBindJSON(&createParams); err != nil {
		controller.Fail(c, controller.ParamsError, err.Error())
		return
	}

	//参数验证
	validate := validator.New()
	if err := validate.Struct(createParams); err != nil {
		controller.Fail(c, controller.ParamsError, err.Error())
		return
	}

	userId := c.GetInt("user_id")

	//会话和自己不匹配
	var conversation model.CozeConversation
	conversation, err := conversation.GetConversation(createParams.ConversationId, userId)
	if err != nil {
		controller.Fail(c, controller.BusinessError, "会话不存在")
		return
	}
	db := model.GetInstance().GetDB()

	//抽取历史上下文
	var messageHistory []model.CozeChat
	if err := db.Model(&model.CozeChat{}).Debug().
		Where("conversation_id = ?", createParams.ConversationId).
		Where("user_id = ?", userId).
		Order("created_at DESC").
		Limit(config.DefaultConfig.Coze.HistoryContextCount).
		Find(&messageHistory).Error; err != nil {
	}

	//将历史上下文顺序反转
	messageHistoryReverse := make([]model.CozeChat, 0)
	for i := len(messageHistory) - 1; i >= 0; i-- {
		messageHistoryReverse = append(messageHistoryReverse, messageHistory[i])
	}

	//将历史上下文转换为coze.Message
	var cozeMessages []*coze.Message
	for _, message := range messageHistoryReverse {
		switch message.Type {
		case "question":
			cozeMessages = append(cozeMessages, coze.BuildUserQuestionText(message.Content, nil))
		case "answer":
			cozeMessages = append(cozeMessages, coze.BuildAssistantAnswer(message.Content, nil))
		}
	}

	//追加当前问题
	cozeMessages = append(cozeMessages, coze.BuildUserQuestionText(createParams.Message, nil))

	//问题入库
	db.Model(&model.CozeChat{}).
		Create(map[string]interface{}{
			"user_id":         userId,
			"conversation_id": createParams.ConversationId,
			"bot_id":          config.DefaultConfig.Coze.BotID,
			"content":         createParams.Message,
			"content_type":    "text",
			"type":            "question",
			"created_at":      time.Now(),
			"status":          1,
		})

	// Get an access_token through personal access token or oauth.
	token := auth.GetCozeAccessToken()
	botID := config.DefaultConfig.Coze.BotID

	authCli := coze.NewTokenAuth(token)

	// Init the Coze client through the access_token.
	cozeCli := coze.NewCozeAPI(authCli, coze.WithBaseURL(config.DefaultConfig.Coze.ApiBase))

	// Step one, create chats
	req := &coze.CreateChatsReq{
		ConversationID: createParams.ConversationId,
		BotID:          botID,
		UserID:         strconv.Itoa(userId),
		Messages:       cozeMessages,
	}

	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
	defer cancel()

	resp, err := cozeCli.Chat.Stream(ctx, req)
	if err != nil {
		logger.Error("Error starting chats: %v\n", err)
		return
	}

	// 设置响应头
	c.Header("Content-Type", "text/event-stream")
	c.Header("Cache-Control", "no-cache")
	c.Header("Connection", "keep-alive")
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("X-Accel-Buffering", "no")
	c.Header("Transfer-Encoding", "chunked")

	// 确保初始响应被发送
	c.Writer.Flush()

	// 发送一个初始消息确保连接建立
	fmt.Fprintf(c.Writer, "data: {\"event\":\"connected\"}\n\n")
	c.Writer.Flush()

	defer resp.Close()

	for {
		event, err := resp.Recv()
		if errors.Is(err, io.EOF) {
			fmt.Fprintf(c.Writer, "data: [DONE]\n\n")
			c.Writer.Flush()
			break
		}
		if err != nil {
			logger.Error("Error receiving event: %v\n", err)
			break
		}

		// 检查 Message 是否为 nil
		if event.Message == nil {
			continue
		}

		// 构造要返回的事件数据
		response := map[string]interface{}{
			"event": event.Event,
			"message": map[string]interface{}{
				"role":            event.Message.Role,
				"type":            event.Message.Type,
				"content":         event.Message.Content,
				"content_type":    event.Message.ContentType,
				"id":              event.Message.ID,
				"conversation_id": event.Message.ConversationID,
				"section_id":      event.Message.SectionID,
				"bot_id":          event.Message.BotID,
				"chat_id":         event.Message.ChatID,
				"created_at":      event.Message.CreatedAt,
				"updated_at":      event.Message.UpdatedAt,
			},
		}

		// 序列化为JSON
		responseJSON, err := json.Marshal(response)
		if err != nil {
			logger.Error("Error marshaling response: %v\n", err)
			continue
		}

		// 使用SSE格式发送完整的事件数据
		fmt.Fprintf(c.Writer, "data: %s\n\n", string(responseJSON))
		c.Writer.Flush()

		// 如果是完成事件，处理入库
		if event.Event == coze.ChatEventConversationMessageCompleted {
			if event.Message.Type == "answer" {
				// 回答入库
				db.Model(&model.CozeChat{}).
					Create(map[string]interface{}{
						"user_id":         userId,
						"conversation_id": createParams.ConversationId,
						"chat_id":         event.Message.ID,
						"bot_id":          config.DefaultConfig.Coze.BotID,
						"content":         event.Message.Content,
						"content_type":    event.Message.ContentType,
						"type":            "answer",
						"created_at":      time.Now(),
						"status":          1,
					})
			}
		}
	}
}
